home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C++ / Applications / PICSee Dust 1.01 / Quaternary Source / GraphicsBuffers.c < prev    next >
Text File  |  1995-11-24  |  20KB  |  687 lines

  1. /*
  2.     GraphicsBuffer.c file, Macintosh platform version.
  3.     by Hiep Dam
  4.     Version 4.0
  5.     Last update: Sept 1995
  6.     
  7.     Copyright ©1995 by Hiep Dam, All Rights Reserved
  8.     You may freely use GraphicsBuffers.h, GraphicsBuffers.c
  9.     in your own applications.
  10.     
  11.     Version History
  12.     1.0        94?            Private work.
  13.     2.0        Late 94?    Changed to GrafixInfo. Added stuff, but still private
  14.                         and not yet released.
  15.  
  16.     3.0        6/23/95        First public release, changed name to GraphicsBuffers
  17.                         and added A LOT more stuff and optimizations, including
  18.                         assembly routines.
  19.  
  20.     3.0.1    6/23/95        Added a few assertions, which 1) Popped open a bug or so
  21.                         which was previously "hidden" and 2) Revealed a subtle
  22.                         problem with the 2, 4 and 8 pixel width multiple
  23.                         restriction (i.e. clipping still might interefere
  24.                         with the width multiple restriction! aargh!). Ah, the
  25.                         value of assertions...
  26.                         You can workaround the clip problem by making sure
  27.                         you never need to clip your sprite (ie all parts of
  28.                         it will always be on the screen); that or make sure
  29.                         that as it moves off the boundaries, it moves off in
  30.                         multiples of 2, 4, or 8 [whichever is required].
  31.  
  32.     3.1        6/30/95        Added and changed a few things; thanks to Macneil
  33.                         Shonle for his comments and suggestions.
  34.                         Made many changes for future compatibility with
  35.                         cross-platform implementations:
  36.                             - Privatized GraphicsBuffer structure
  37.                             - Removed SetMonitorDepth()
  38.                         The code has also been rearranged and cleaned up.
  39.     
  40.     3.1.1    7/3/95        Changed prototypes slightly for cross-platform
  41.                         compatibility.
  42.                         With the addition of CP_Data.h, the GraphicsBuffers.h
  43.                         file is now compatible with Windows. All I have to
  44.                         do now is to write the Windows implementation of
  45.                         GraphicsBuffer.c...
  46.     
  47.     4.0        9/28/95        Header file revamped; some routines changed slightly
  48.                         in parameters.
  49.                         Contents of GraphicsBuffers.c file cleaned up.
  50.                         Split up blitters into associated files organized by
  51.                         depth.
  52.     
  53.     4.0.1    10/31/95    Added gTransferMode support and the Get/Set
  54.                         GraphicsBuffers field member routines.
  55.     
  56.     4.0.2    11/1/95        Fixed bug in GraphicsBufferBlitter_16.c (the C version
  57.                         of the 16-bit transparent blitter). Will look for bugs
  58.                         in all the other files [due to mis-casting of TwoPixelsPtr_16bit]
  59.     
  60.     4.0.3    11/2/95        Fixed minor issues to make code compatible with
  61.                         Symantec C++/THINK C 8.0
  62. */
  63.  
  64.  
  65. #include "GraphicsBuffers.h"
  66. #include "GraphicsBufferPriv.h"
  67.  
  68. // ---------------------------------------------------------------------------
  69.  
  70. #define kStripRowBytesMask    0x7FFF
  71.  
  72. // ---------------------------------------------------------------------------
  73.  
  74. // Related to the blitters only.
  75. SignedByte gMMUMode        = true32b;
  76. Boolean gNotIn32Mode    = false;
  77. short gTransferMode        = srcCopy;
  78.  
  79. BlitInfo mBlitInfo;
  80.  
  81. // ---------------------------------------------------------------------------
  82.  
  83. static GBErr UpdateCachedData(
  84.     GraphicsBufferPtr    buffer,
  85.     long                cache,
  86.     long                pixelDepth,
  87.     const CP_Rect        *bounds);
  88.  
  89. // ==========================================================================
  90.  
  91. GBErr InitGraphicsBuffers() {
  92.     gMMUMode        = GetMMUMode();
  93.     gNotIn32Mode    = (gMMUMode != true32b);
  94.  
  95.     return(kGBNoErr);
  96. } // END InitGraphicsBuffers
  97.  
  98. // ---------------------------------------------------------------------------
  99.  
  100. GBErr NewGraphicsBuffer(
  101.     GraphicsBufferPtr    *buffer,
  102.     CP_ULong            pixelDepth,
  103.     const CP_Rect        *boundsRect,
  104.     CP_ULong            flags,
  105.     CP_ULong            cache) {
  106.  
  107.     GraphicsBufferPrivPtr gb;
  108.     GBErr err = kGBNoErr;
  109.  
  110.     ASSERT(!(boundsRect == NULL));
  111.     ASSERT(!(cache != true && cache != false));
  112.  
  113.     *buffer = NULL;
  114.  
  115.     /* Allocate chunk of memory for a GraphicsBuffer structure */
  116.     gb = (GraphicsBufferPrivPtr)NewPtrClear(sizeof(GraphicsBuffer));
  117.     if (gb == NULL)
  118.         return(kGBNoMemAvailErr);    // or call MemError()
  119.  
  120.     gb->gworld = NULL;
  121.     err = NewGWorld(&gb->gworld, pixelDepth, boundsRect, NULL, NULL, flags);
  122.     if (err != noErr)
  123.         return(kGBOSErr);    // or return err itself
  124.     else {
  125.         err = UpdateCachedData(gb, cache, pixelDepth, boundsRect);
  126.     }
  127.  
  128.     *buffer = (GraphicsBufferPtr)gb;
  129.     return(err);
  130. } // END NewGraphicsBuffer
  131.  
  132. // ---------------------------------------------------------------------------
  133.  
  134. GBErr UpdateGraphicsBuffer(
  135.     GraphicsBufferPtr    buffer,
  136.     long                pixelDepth,
  137.     const CP_Rect        *boundsRect,
  138.     long                flags,
  139.     long                cache) {
  140. /*
  141.     See NewGraphicsBuffer() for explanation of the arguments.
  142.  
  143.     NOTE: For argument buffer, on input it should be a pointer to an
  144.     *existing* GraphicsBuffer.
  145.     Notice the difference in arguments here from UpdateGWorld. In
  146.     UpdateGWorld, you pass a pointer to a GWorldPtr; here you just
  147.     pass a pointer to a GraphicsBuffer (not a pointer to a GraphicsBufferPtr).
  148.  
  149.     Most of the time you'll want to call this after first creating your
  150.     GraphicsBuffer, and then having to change the depth of your monitor
  151.     and buffer. Pass a depth of 0 and flags of kGBOptimalFlag.
  152. */
  153.     GraphicsBufferPrivPtr gb;
  154.     GBErr err;
  155.     GWorldFlags gwErr;
  156.     
  157.     ASSERT(!(boundsRect == NULL));
  158.     ASSERT(!(cache != true && cache != false));
  159.  
  160.     if (buffer == NULL) return(paramErr);
  161.  
  162.     UnlockGraphicsBuffer(buffer);
  163.     gb = (GraphicsBufferPrivPtr)buffer;
  164.     
  165.     gwErr = UpdateGWorld(&gb->gworld, pixelDepth, boundsRect, NULL, NULL, flags);
  166.     if (gwErr == gwFlagErr)
  167.         return(kGBOSErr);    // or QDError()
  168.  
  169.     /* Update cached data */
  170.     if (gb->rowAddressOffsets != NULL) {
  171.         DisposePtr((Ptr)gb->rowAddressOffsets);
  172.     }
  173.     err = UpdateCachedData(gb, cache, pixelDepth, boundsRect);
  174.  
  175.     return(kGBNoErr);
  176. } // END UpdateGraphicsBuffer
  177.  
  178. // ---------------------------------------------------------------------------
  179.  
  180. GBErr UpdateCachedData(
  181.     GraphicsBufferPtr    buffer,
  182.     long                cache,
  183.     long                pixelDepth,
  184.     const CP_Rect        *bounds) {
  185. /*
  186.     Note: this routine will not work with buffers of type kVideoMemoryBuffer!
  187. */
  188.     GraphicsBufferPrivPtr gb;
  189.     GWorldPtr saveWorld;
  190.     GDHandle saveDev;
  191.  
  192.     ASSERT(!(buffer == NULL));
  193.     ASSERT(!(bounds == NULL));
  194.     ASSERT(!(cache != true && cache != false));
  195.  
  196.     gb = (GraphicsBufferPtr)buffer;
  197.     (void)LockPixels(GetGWorldPixMap(gb->gworld));
  198.  
  199.         // Make it nice 'n clean: erase gworld first
  200.     GetGWorld(&saveWorld, &saveDev);
  201.     SetGWorld(gb->gworld, NULL);
  202.     EraseRect(&gb->localBounds);
  203.     SetGWorld(saveWorld, saveDev);
  204.  
  205.     gb->bufferType = kGraphicsBuffer;
  206.     gb->bufferDepth = pixelDepth;
  207.     gb->window = NULL;
  208.  
  209.     gb->pixmap = GetGWorldPixMap(gb->gworld);
  210.     /* The rowBytes value in the pixmap can't be used directly. The highest
  211.        bit is used to determine whether it's a bitmap or pixmap. So we have
  212.        to strip this value off, using 7FFF -> 0111 1111 1111 1111
  213.     */
  214.     gb->realRowBytes = (kStripRowBytesMask & (**(gb->pixmap)).rowBytes);
  215.     gb->rowBytesDiv4 = gb->realRowBytes / 4;
  216.     gb->rowBytesDiv2 = gb->realRowBytes / 2;
  217.  
  218.     SetRect(&gb->videoBounds, 0, 0, 0, 0);
  219.     gb->localBounds = *bounds;
  220.     gb->globBounds = *bounds;
  221.     OffsetRect(&gb->localBounds, -gb->localBounds.left,
  222.         -gb->localBounds.top);
  223.     if (gb->globBounds.left != 0 || gb->globBounds.top != 0)
  224.         gb->bufferFlushedTopLeft = false;
  225.     else
  226.         gb->bufferFlushedTopLeft = true;
  227.  
  228.     if (cache) {
  229.         long bufferHeight;
  230.         unsigned long i;
  231.  
  232.         gb->bufferCached = true;
  233.  
  234.         // Create our pre-calculated "realRowBytes * vertCoords"
  235.         bufferHeight = gb->localBounds.bottom - gb->localBounds.top;
  236.         gb->rowAddressOffsets = (unsigned long*)NewPtr
  237.             (sizeof(unsigned long) * bufferHeight);
  238.         if (gb->rowAddressOffsets == NULL)
  239.             return(kGBNoMemAvailErr);    // or MemError()
  240.  
  241.         /* Now do the actual precalculations: long multiply */
  242.         for (i = 0; i < bufferHeight; i++) {
  243.             gb->rowAddressOffsets[i] = gb->realRowBytes * i;
  244.         }
  245.     }
  246.     else {
  247.         /* If there is no cache, update flag */
  248.         if (gb->rowAddressOffsets == NULL)
  249.             gb->bufferCached = false;
  250.         else
  251.             gb->bufferCached = true;
  252.     }
  253.     
  254.     return(noErr);
  255. } // END UpdateCachedData
  256.  
  257. // ---------------------------------------------------------------------------
  258.  
  259. GBErr DisposeGraphicsBuffer(GraphicsBufferPtr buffer) {
  260.     GraphicsBufferPrivPtr gb;
  261.  
  262.     ASSERT(buffer != NULL);
  263.     if (buffer == NULL)
  264.         return(kGBParamErr);
  265.  
  266.     gb = (GraphicsBufferPrivPtr)buffer;
  267.  
  268.     /* Dispose contents of GraphicsBuffer */
  269.     if (gb->gworld != NULL) {
  270.         UnlockPixels(gb->pixmap);
  271.         DisposeGWorld(gb->gworld);
  272.     }
  273.     if (gb->rowAddressOffsets != NULL)
  274.         DisposePtr((Ptr)gb->rowAddressOffsets);
  275.  
  276.     /* Dispose GraphicsBuffer itself */
  277.     DisposePtr((Ptr)gb);
  278.  
  279.     return(noErr);
  280. } // END DisposeGraphicsBuffer
  281.  
  282. // ---------------------------------------------------------------------------
  283.  
  284. GBErr Convert2GraphicsBuffer(
  285.     GraphicsBufferPtr    *buffer,
  286.     CP_Window_Ref        srcWind,
  287.     const CP_Rect        *bounds,
  288.     long                cache) {
  289. /*
  290.     Bounds should be in global coordinates of the window.
  291. */
  292.         // Some local variables...
  293.     Rect testRect;
  294.     GraphicsBufferPrivPtr gb;
  295.     GDHandle monitor;
  296.     unsigned long i;
  297.  
  298.     ASSERT(!(bounds == NULL));
  299.     ASSERT(!(srcWind == NULL));
  300.     ASSERT(!(cache != true && cache != false));
  301.  
  302.     *buffer = NULL;
  303.  
  304.     gb = (GraphicsBufferPrivPtr)NewPtrClear(sizeof(GraphicsBuffer));
  305.     if (gb == NULL)
  306.         return(kGBNoMemAvailErr);    // or MemError() instead
  307.  
  308.         // We're creating a GraphicsBuffer from window and monitor data, so we
  309.         // won't need to create a gworld.
  310.     gb->gworld = NULL;
  311.     gb->window = srcWind;
  312.  
  313.     gb->bufferType = kVideoMemoryBuffer;
  314.  
  315.     /* Given the global bounds of the window, find the corresponding
  316.        monitor; we'll assume the window lies wholly inside one monitor
  317.        only and it doesn't intersect any other monitors */
  318.     monitor = GetDeviceList();
  319.     while (monitor != NULL) {
  320.         testRect = (**monitor).gdRect;
  321.         if (SectRect(bounds, &testRect, &testRect))
  322.             break;
  323.         monitor = GetNextDevice(monitor);
  324.     }
  325.     if (monitor == NULL)
  326.         return(kGBParamErr);
  327.  
  328.     gb->pixmap = (**monitor).gdPMap;
  329.     gb->realRowBytes = (kStripRowBytesMask & (**(gb->pixmap)).rowBytes);
  330.     gb->rowBytesDiv4 = gb->realRowBytes / 4;
  331.     gb->rowBytesDiv2 = gb->realRowBytes / 2;
  332.  
  333.     gb->videoBounds = (**monitor).gdRect; // or (**gb->pixmap).bounds;
  334.     gb->localBounds = *bounds;
  335.     gb->globBounds = *bounds;
  336.     OffsetRect(&gb->localBounds, -gb->localBounds.left,
  337.         -gb->localBounds.top);
  338.     if (gb->globBounds.left != 0 || gb->globBounds.top != 0)
  339.         gb->bufferFlushedTopLeft = false;
  340.     else
  341.         gb->bufferFlushedTopLeft = true;
  342.  
  343.     if (cache) {
  344.         long bufferHeight = gb->videoBounds.bottom - gb->videoBounds.top;
  345.         gb->bufferCached = true;
  346.  
  347.         // Create our pre-calculated "realRowBytes * vertCoords"
  348.         gb->rowAddressOffsets = (unsigned long*)NewPtr
  349.             (sizeof(unsigned long) * (bufferHeight));
  350.         if (gb->rowAddressOffsets == NULL)
  351.             return(kGBNoMemAvailErr);    // or MemError()
  352.     
  353.         for (i = 0; i < bufferHeight; i++)
  354.             gb->rowAddressOffsets[i] = gb->realRowBytes * i;
  355.     }
  356.     else {
  357.         gb->bufferCached = false;
  358.         gb->rowAddressOffsets = NULL;
  359.     }
  360.  
  361.     *buffer = (GraphicsBufferPtr)gb;
  362.     return(noErr);
  363. } // END Convert2GraphicsBuffer
  364.  
  365. // ---------------------------------------------------------------------------
  366.  
  367. void SetGraphicsBuffer(const GraphicsBufferPtr buffer) {
  368. /*
  369.     Analogous to SetGWorld()
  370. */
  371.     GraphicsBufferPrivPtr gb = (GraphicsBufferPrivPtr)buffer;
  372.  
  373.     ASSERT(buffer != NULL);
  374.  
  375.     if (gb->gworld != NULL)
  376.         SetGWorld(gb->gworld, NULL);
  377. } // END SetGraphicsBuffer
  378.  
  379. // ---------------------------------------------------------------------------
  380.  
  381. Boolean LockGraphicsBuffer(const GraphicsBufferPtr buffer) {
  382. /*
  383.     Analogous to LockGWorld()
  384. */
  385.     GraphicsBufferPrivPtr gb = (GraphicsBufferPrivPtr)buffer;
  386.  
  387.     ASSERT(buffer != NULL);
  388.  
  389.     if (gb->gworld != NULL)
  390.         return(LockPixels(gb->pixmap));
  391.     else
  392.         return(false);
  393. } // END LockGraphicsBuffer
  394.  
  395. // ---------------------------------------------------------------------------
  396.  
  397. void UnlockGraphicsBuffer(const GraphicsBufferPtr buffer) {
  398. /*
  399.     Analogous to UnlockGWorld()
  400. */
  401.     GraphicsBufferPrivPtr gb = (GraphicsBufferPrivPtr)buffer;
  402.  
  403.     ASSERT(buffer != NULL);
  404.  
  405.     if (gb->gworld != NULL)
  406.         UnlockPixels(gb->pixmap);
  407. } // END UnlockGraphicsBuffer
  408.  
  409. // ---------------------------------------------------------------------------
  410.  
  411. void SetGraphicsEnvironment(const GraphicsEnvPtr environs) {
  412.     ASSERT(environs != NULL);
  413.     
  414.     SetGWorld((GWorldPtr)environs->reserved0, (GDHandle)environs->reserved1);
  415. } // END SetGraphicsEnvironment
  416.  
  417. // ---------------------------------------------------------------------------
  418.  
  419. void GetGraphicsEnvironment(GraphicsEnvPtr environs) {
  420.     GWorldPtr saveGWorld;
  421.     GDHandle saveDevice;
  422.  
  423.     ASSERT(environs != NULL);
  424.     
  425.     GetGWorld(&saveGWorld, &saveDevice);
  426.     environs->reserved0 = (void*)saveGWorld;
  427.     environs->reserved1 = (void*)saveDevice;
  428. } // END GetGraphicsEnvironment
  429.  
  430. // ---------------------------------------------------------------------------
  431.  
  432. void CopyGraphicsBuffer(
  433.     GraphicsBufferPtr    srcBuffer,
  434.     GraphicsBufferPtr    destBuffer,
  435.     const CP_Rect        *srcR,
  436.     const CP_Rect        *destR) {
  437.  
  438.     GraphicsBufferPrivPtr sBuffer;
  439.     GraphicsBufferPrivPtr dBuffer;
  440.  
  441.     ASSERT(!(srcBuffer == NULL));
  442.     ASSERT(!(destBuffer == NULL));
  443.     ASSERT(!(srcR == NULL));
  444.     ASSERT(!(destR == NULL));
  445.  
  446.     sBuffer = (GraphicsBufferPrivPtr)srcBuffer;
  447.     dBuffer = (GraphicsBufferPrivPtr)destBuffer;
  448.  
  449.     if (dBuffer->gworld != NULL)
  450.         // Just copying between pixmaps.
  451.         CopyBits((BitMap*)(*sBuffer->pixmap),
  452.             (BitMap*)(*dBuffer->pixmap),
  453.             srcR, destR, gTransferMode, NULL);
  454.     else if (dBuffer->window != NULL)
  455.         // Copying to window
  456.         CopyBits((BitMap*)(*sBuffer->pixmap),
  457.             (&dBuffer->window->portBits),
  458.             srcR, destR, gTransferMode, NULL);
  459.     else {
  460.         // do nothing...
  461.         SysBeep(10);
  462.     }
  463. } // END CopyGraphicsBuffer
  464.  
  465. // ---------------------------------------------------------------------------
  466.  
  467. void CopyGraphicsBuffer2Window(
  468.     GraphicsBufferPtr    srcBuffer,
  469.     CP_Window_Ref        destWind,
  470.     const CP_Rect        *srcR,
  471.     const CP_Rect        *destR) {
  472.  
  473.     GraphicsBufferPrivPtr sBuffer;
  474.  
  475.     ASSERT(!(srcBuffer == NULL));
  476.     ASSERT(!(destWind == NULL));
  477.     ASSERT(!(srcR == NULL));
  478.     ASSERT(!(destR == NULL));
  479.  
  480.     sBuffer = (GraphicsBufferPrivPtr)srcBuffer;
  481.  
  482.     LockPixels(GetGWorldPixMap(sBuffer->gworld));
  483.     if (sBuffer->gworld != NULL)
  484.         CopyBits((BitMap*)&((GrafPtr)sBuffer->gworld)->portBits, &destWind->portBits, 
  485.             srcR, destR, gTransferMode, NULL);
  486.     else if (sBuffer->window != NULL)
  487.         CopyBits((&sBuffer->window->portBits), &destWind->portBits, 
  488.             srcR, destR, gTransferMode, NULL);
  489.     else {
  490.         SysBeep(10);
  491.     }
  492.  
  493.     /*
  494.     if (sBuffer->gworld != NULL)
  495.         CopyBits((BitMap*)(*sBuffer->pixmap), &destWind->portBits, 
  496.             srcR, destR, gTransferMode, NULL);
  497.     else if (sBuffer->window != NULL)
  498.         CopyBits((&sBuffer->window->portBits), &destWind->portBits, 
  499.             srcR, destR, gTransferMode, NULL);
  500.     else {
  501.         SysBeep(10);
  502.     }
  503.     */
  504. } // END CopyGraphicsBuffer2Window
  505.  
  506. // ---------------------------------------------------------------------------
  507.  
  508. void CopyWindow2GraphicsBuffer(
  509.     CP_Window_Ref        srcWind,
  510.     GraphicsBufferPtr    destBuffer,
  511.     const CP_Rect        *srcR,
  512.     const CP_Rect        *destR) {
  513.  
  514.     GraphicsBufferPrivPtr dBuffer;
  515.  
  516.     ASSERT(!(srcWind == NULL));
  517.     ASSERT(!(destBuffer == NULL));
  518.     ASSERT(!(srcR == NULL));
  519.     ASSERT(!(destR == NULL));
  520.  
  521.     dBuffer = (GraphicsBufferPrivPtr)destBuffer;
  522.  
  523.     if (dBuffer->gworld != NULL)
  524.         CopyBits(&srcWind->portBits, (BitMap*)(*dBuffer->pixmap), 
  525.             srcR, destR, gTransferMode, NULL);
  526.     else if (dBuffer->window != NULL)
  527.         CopyBits(&srcWind->portBits, (&dBuffer->window->portBits), 
  528.             srcR, destR, gTransferMode, NULL);
  529.     else {
  530.         SysBeep(10);
  531.     }
  532. } // END CopyWindow2GraphicsBuffer
  533.  
  534. // ---------------------------------------------------------------------------
  535.  
  536. void CopyGraphicsBufferRegion(
  537.     GraphicsBufferPtr    srcBuffer,
  538.     GraphicsBufferPtr    destBuffer,
  539.     const CP_Rect        *srcR,
  540.     const CP_Rect        *destR,
  541.     CP_Region_Hdl        maskRgn) {
  542.  
  543.     GraphicsBufferPrivPtr sBuffer;
  544.     GraphicsBufferPrivPtr dBuffer;
  545.  
  546.     ASSERT(!(srcBuffer == NULL));
  547.     ASSERT(!(destBuffer == NULL));
  548.     ASSERT(!(srcR == NULL));
  549.     ASSERT(!(destR == NULL));
  550.     ASSERT(!(maskRgn == NULL));
  551.  
  552.     sBuffer = (GraphicsBufferPrivPtr)srcBuffer;
  553.     dBuffer = (GraphicsBufferPrivPtr)destBuffer;
  554.  
  555.     if (dBuffer->gworld != NULL)
  556.         CopyBits((BitMap*)(*sBuffer->pixmap),
  557.             (BitMap*)(*dBuffer->pixmap),
  558.             srcR, destR, gTransferMode, maskRgn);
  559.     else if (dBuffer->window != NULL)
  560.         CopyBits((BitMap*)(*sBuffer->pixmap),
  561.             (&dBuffer->window->portBits),
  562.             srcR, destR, gTransferMode, maskRgn);
  563. } // END CopyGraphicsBufferRegion
  564.  
  565. // ---------------------------------------------------------------------------
  566.  
  567. void CopyGraphicsBufferMask(
  568.     GraphicsBufferPtr    srcBuffer,
  569.     GraphicsBufferPtr    destBuffer,
  570.     const CP_Rect        *srcR,
  571.     const CP_Rect        *destR,
  572.     GraphicsBufferPtr    maskBuffer) {
  573.  
  574.     GraphicsBufferPrivPtr sBuffer;
  575.     GraphicsBufferPrivPtr dBuffer;
  576.     GraphicsBufferPrivPtr mBuffer;
  577.  
  578.     ASSERT(!(srcBuffer == NULL));
  579.     ASSERT(!(destBuffer == NULL));
  580.     ASSERT(!(srcR == NULL));
  581.     ASSERT(!(destR == NULL));
  582.     ASSERT(!(maskBuffer == NULL));
  583.  
  584.     sBuffer = (GraphicsBufferPrivPtr)srcBuffer;
  585.     dBuffer = (GraphicsBufferPrivPtr)destBuffer;
  586.     mBuffer = (GraphicsBufferPrivPtr)maskBuffer;
  587.  
  588.     if (dBuffer->gworld != NULL)
  589.         CopyMask((BitMap*)(*sBuffer->pixmap),
  590.             (BitMap*)(*mBuffer->pixmap),
  591.             (BitMap*)(*dBuffer->pixmap),
  592.             srcR, srcR, destR);
  593.     else if (dBuffer->window != NULL)
  594.         CopyMask((BitMap*)(*sBuffer->pixmap),
  595.             (BitMap*)(*mBuffer->pixmap),
  596.             (&dBuffer->window->portBits),
  597.             srcR, srcR, destR);
  598. } // END CopyGraphicsBufferMask
  599.  
  600. // ---------------------------------------------------------------------------
  601.  
  602. void CopyGraphicsBufferTransparent(
  603.     GraphicsBufferPtr    srcBuffer,
  604.     GraphicsBufferPtr    destBuffer,
  605.     const CP_Rect        *srcR,
  606.     const CP_Rect        *destR,
  607.     GraphicsBufferPtr    _notUsed) {
  608.  
  609.     GraphicsBufferPrivPtr sBuffer;
  610.     GraphicsBufferPrivPtr dBuffer;
  611.  
  612.     ASSERT(!(srcBuffer == NULL));
  613.     ASSERT(!(destBuffer == NULL));
  614.     ASSERT(!(srcR == NULL));
  615.     ASSERT(!(destR == NULL));
  616.  
  617.     sBuffer = (GraphicsBufferPrivPtr)srcBuffer;
  618.     dBuffer = (GraphicsBufferPrivPtr)destBuffer;
  619.  
  620.     if (dBuffer->gworld != NULL)
  621.         // Just copying between pixmaps.
  622.         CopyBits((BitMap*)(*sBuffer->pixmap),
  623.             (BitMap*)(*dBuffer->pixmap),
  624.             srcR, destR, transparent, NULL);
  625.     else if (dBuffer->window != NULL)
  626.         // Copying to window
  627.         CopyBits((BitMap*)(*sBuffer->pixmap),
  628.             (&dBuffer->window->portBits),
  629.             srcR, destR, transparent, NULL);
  630.     else {
  631.         // do nothing...
  632.     }
  633. } // END CopyGraphicsBufferTransparent
  634.  
  635. // ---------------------------------------------------------------------------
  636.  
  637. long GetGraphicsBufferType(GraphicsBufferPtr buffer) {
  638.     return(((GraphicsBufferPrivPtr)buffer)->bufferType);
  639. } // END GetGraphicsBufferType
  640.  
  641. // ---------------------------------------------------------------------------
  642.  
  643. long GetGraphicsBufferDepth(GraphicsBufferPtr buffer) {
  644.     return(((GraphicsBufferPrivPtr)buffer)->bufferDepth);
  645. } // END GetGraphicsBufferDepth
  646.  
  647. // ---------------------------------------------------------------------------
  648.  
  649. void *GetGraphicsBufferPixelAddress(GraphicsBufferPtr buffer) {
  650.     return(GetPixBaseAddr(((GraphicsBufferPrivPtr)buffer)->pixmap));
  651. } // END GetGraphicsBufferPixelAddress
  652.  
  653. // ---------------------------------------------------------------------------
  654.  
  655. unsigned long GetGraphicsBufferRowBytes(GraphicsBufferPtr buffer) {
  656.     return(((GraphicsBufferPrivPtr)buffer)->realRowBytes);
  657. } // END GetGraphicsBufferRowBytes
  658.  
  659. // ---------------------------------------------------------------------------
  660.  
  661. void GetGraphicsBufferBounds(GraphicsBufferPtr buffer, CP_Rect *globalBounds) {
  662.     GraphicsBufferPrivPtr gb = (GraphicsBufferPrivPtr)buffer;
  663.     *globalBounds = gb->globBounds;
  664. } // END GetGraphicsBufferBounds
  665.  
  666. // ---------------------------------------------------------------------------
  667.  
  668. void SetGraphicsBufferTransferMode(short newMode) {
  669.     gTransferMode = newMode;
  670. } // END SetGraphicsBufferTransferMode
  671.  
  672. // ---------------------------------------------------------------------------
  673.  
  674. short GetGraphicsBufferTransferMode() {
  675.     return(gTransferMode);
  676. } // END GetGraphicsBufferTransferMode
  677.  
  678. // ---------------------------------------------------------------------------
  679.  
  680. GWorldPtr GetGraphicsBufferGWorld(GraphicsBufferPtr buffer) {
  681.     GraphicsBufferPrivPtr gb = (GraphicsBufferPrivPtr)buffer;
  682.     return(gb->gworld);
  683. } // END GetGraphicsBufferGWorld
  684.  
  685. // ==========================================================================
  686.  
  687. // END GraphicsBuffers.c